接上一篇AWS API Gateway + Lambda + Slack App - 新建 slash command,这一篇介绍怎么用 aws lambda + api gateway + dynamodb 添加 slash command /todo,完成 to-do list 的增、删、查等任务。两个重点,一是连接 dynamodb,二是创建 slack interactive message,具体到这篇的例子,是实现 message button。
DynamoDB configuration
Amazon DynamoDB 属于 NoSQL 数据库,支持文档和 key-value 存储模型。每一行是一个 item,item 时属性(attributes) 的集合,每个 attribute 都有各自的名称(name)和值(value)。DynamoDB 提供了 item 的 4 项基本操作,创建(PutItem)/读取(GetItem)/更新(UpdateItem)/删除(DeleteItem)。
Create table
第一步,完成 todolist table 的创建,aws console 进入dynamodb,选 create table,做如下设置,primary key 设为 user,一个 user 一个 item,item 有属性 todos,类型是 list,一个 user 当然可以有多个 to-do item,都保存在 todos 的 list 中。当然,之后会有更多的属性,比如说 channel, priority 等,后面再做设置。
建表完成后在 Items 标签下 Create item,做如下设置,方便后面的测试。
Attach policy to IAM role
接下来是测试 lambda function 能否连接数据库,默认情况下,lambda function 是没有这个权限的,我们需要创建一个 role,或者在已有的 role 上 attach 相应的 policy,再对 lambda function 采用这个 role,才可以访问数据库。所以,先从aws console 进入IAM,选择 Roles 以及 lambda configuration 中的 role,比如说 lambda_basic_execution(这里以 kmsDecrypt role 为例),选择 inline policy 来创建并且 attach policy。
Step 1: create inline policy
Step 2: generate policy
Step 3: edit permissions
ARN 在 DynamoDB 页面 table overview 下可以找到,这里的 permission 表示使用了这个 role 的 lambda function 只可以对 todolist 这张表进行操作,Actions 是操作类型,这里选 All Actions,表示增删改查所有操作都允许。
Step 4: review and apply policy
Policy 的具体内容
|
|
Lambda configuration
写一个简单的 lambda function 看看能不能读取表中内容
连接成功
连接不成功可能是因为地区不一致,可以显性指定 region 来连接。
下一部分附上 debug 过程,提供可能的 debug 思路。
Possible error/Debug process
有可能出现 “module initialization error”,具体错误信息是
把上一步的 policy 改的 less restrict 一些,方便调试
再重新 test 一下 lambda,发现错误变成了 Requested resource not found
根本没这个 table,怎么办?那干脆把所有 table 列出来看看喽,修改 lambda function,
发现 table list 为空。
这时候熟悉 aws 的朋友就知道,Region! Region! Region! 一定要一致!
再来回顾下 dynamodb table overview,发现 table 所在 region 是 US WEST,而我们的 lambda ARN 是在 US EAST,所以办法是在连接 table 的时候直接指定地区。
|
|
连接成功。
Slash command configuration
在 slack app 页面新建 slash command /todo,command 以及 api gateway 的设置,具体参照AWS API Gateway + Lambda + Slack App - 新建 slash command,非常简单的过程。
Slack Message Button
先来看一下 message button 的运作流程,slack app 的 interactive messages 下有一个 Request URL,专门用来响应 message button 事件。一个 slack app 只能配置一个 action URL,它会接收所有 channel/team 下的 message button 的所有点击操作,这相当于一个 dispatch station。当用户点击 button 时,action URL 会收到一个 URL encoded request,request 的 body 参数中会包含一个 payload,记录相应的 user action,我们可以通过 payload 来获取用户的点击行为,然后做出响应。
Slack 官方教程 Making messages interactive 提供了多种响应 message action 的方法,主要说来一是直接对 action URL 的 request 进行 response,要求是 3 秒内必须做出响应;二是通过 response_url 进行对原消息的更新等,三是用 chat.update 来更新原始信息。
经尝试,发现在使用 python 以及 slackclient package 的情况下,并不能用 chat.postMessage, chat.update 来实现 message button。slackclient 作为 slack api 的一个 wrapper,确实可以实现 chat.postMessage,但只能提供 basics 的一些 response,并不能处理请求中加 attachments 的情况。
这里采用的是直接响应的方法。首先需要在 API Gateway 中配置 request url,对应的 integration 还是选 todolist lambda function,mapping templates 还是要改成 x-www-form-urlencoded 的形式。
deploy 后记录下 Invoke URL,在 slack app 下修改 request URL
message button format:
上面的 message format 会产生下图的三个 button
如果用户点击 Remind me,这个行为对应的信息会发送到 request url,由于 request url 还是绑定了 todolist 这个 lambda function,所以可以在 lambda 中判断 request 是否包含 payload 参数,如果包含,说明这是一个 button 响应事件,就读取 user action 信息,并响应,否则,就响应 command 命令。
完整的 lambda function 代码,role 用 kmsDecrypt,环境变量设置好 kmsEncryptedToken,参照AWS API Gateway + Lambda + Slack App - 新建 slash command,
|
|